using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace AntEater.ComponentModel
{
    /// <summary>
    /// Represents a collection of build file extensions
    /// </summary>
    [Serializable]
    public class BuildFileExtensionCollection : Collection<string>
    {
        /// <summary>
        /// Occurs when the instance or some of his child objects has changed.
        /// </summary>
        public event EventHandler<EventArgs> Changed;

        /// <summary>
        /// Occurs when the collection changed.
        /// </summary>
        public event EventHandler<CollectionChangeEventArgs> CollectionChanged;

        /// <summary>
        /// Adds a collection of strings to the collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        public void AddRange(IEnumerable<string> collection) {

            if (collection == null) { throw new ArgumentNullException("collection"); }

            foreach (string extension in collection) {
                this.Add(extension);
            }
        }

        /// <summary>
        /// Returns the array.
        /// </summary>
        /// <returns>An array of strings.</returns>
        public string[] ToArray() {
            string[] result = new string[this.Count];
            this.CopyTo(result, 0);

            return result;
        }

        /// <summary>
        /// Determines whether the specified filename is a build file.
        /// </summary>
        /// <param name="filename">The filename.</param>
        /// <returns>
        /// 	<c>true</c> if the specified filename is a build file; otherwise, <c>false</c>.
        /// </returns>
        public bool IsBuildFile(string filename) {

            if (filename == null) { throw new ArgumentNullException("filename"); }

            bool result = false;
            foreach (string extension in this) {
                if (filename.EndsWith(extension, StringComparison.InvariantCulture)) {
                    result = true;
                    break;
                }
            }

            return result;
        }

        /// <summary>
        /// Inserts an element into the <see cref="T:System.Collections.ObjectModel.Collection`1"></see> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which item should be inserted.</param>
        /// <param name="item">The object to insert. The value can be null for reference types.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">index is less than zero.-or-index is greater than <see cref="P:System.Collections.ObjectModel.Collection`1.Count"></see>.</exception>
        protected override void InsertItem(int index, string item) {
            base.InsertItem(index, item);
            this.OnCollectionChanged(CollectionChangeAction.Add);
        }

        /// <summary>
        /// Replaces the element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the element to replace.</param>
        /// <param name="item">The new value for the element at the specified index. The value can be null for reference types.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">index is less than zero.-or-index is greater than <see cref="P:System.Collections.ObjectModel.Collection`1.Count"></see>.</exception>
        protected override void SetItem(int index, string item) {
            base.SetItem(index, item);
            this.OnCollectionChanged(CollectionChangeAction.Refresh);
        }

        /// <summary>
        /// Removes the element at the specified index of the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>.
        /// </summary>
        /// <param name="index">The zero-based index of the element to remove.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">index is less than zero.-or-index is equal to or greater than <see cref="P:System.Collections.ObjectModel.Collection`1.Count"></see>.</exception>
        protected override void RemoveItem(int index) {
            base.RemoveItem(index);
            this.OnCollectionChanged(CollectionChangeAction.Remove);
        }

        /// <summary>
        /// Removes all elements from the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>.
        /// </summary>
        protected override void ClearItems() {
            base.ClearItems();
            this.OnCollectionChanged(CollectionChangeAction.Refresh);
        }

        /// <summary>
        /// Called when [changed].
        /// </summary>
        protected void OnChanged() {
            if (this.Changed != null) {
                this.Changed(this, new EventArgs());
            }
        }

        /// <summary>
        /// Called when [collection changed].
        /// </summary>
        /// <param name="action">The action.</param>
        protected void OnCollectionChanged(CollectionChangeAction action) {
            if (CollectionChanged != null) {
                CollectionChanged(this, new CollectionChangeEventArgs(action, this));
            }
            this.OnChanged();
        }
    }
}
